
import type { DirectiveBinding } from "vue";
import { throttle } from '../hooks/hook'
import { ref } from 'vue';
interface ElType extends HTMLElement {
    copyData?: string | number;
    __handleClick__?: any;
    parentNode: any;
}
function copyToClipboard(value: string) {
    const input = document.createElement("input");
    input.style.opacity = '0';
    input.value = value;
    document.body.appendChild(input);
    input.select();
    document.execCommand("Copy");
    document.body.removeChild(input);
}

export const directivesList = {
    //  *v-copy
    //     * 复制某个值至剪贴板
    //     * 接收参数：string类型/Ref<string>类型/Reactive<string>类型
    copy: {
        mounted(el: ElType, binding: DirectiveBinding) {
            el.addEventListener("click", () => {
                const valueToCopy = binding.value !== undefined ? binding.value.toLocaleString() : el.textContent;
                copyToClipboard(valueToCopy);
            });
        },
        updated(el: ElType, binding: DirectiveBinding) {
            if (el.__handleClick__) {
                el.removeEventListener("click", el.__handleClick__);
            }
            el.__handleClick__ = () => {
                const valueToCopy = binding.value !== undefined ? binding.value.toLocaleString() : el.textContent;
                copyToClipboard(valueToCopy);
            };

            el.addEventListener("click", el.__handleClick__);
        },
        beforeUnmount(el: ElType) {
            if (el.__handleClick__) {
                el.removeEventListener("click", el.__handleClick__);
            }
        },
    },
    // *v-draggable
    // 功能：通过鼠标按住在页面可视区域内任意拖拽元素。
    // 设置需要拖拽的元素为absolute，其父元素为relative。
    // 鼠标按下(onmousedown)时记录目标元素当前的 left 和 top 值。
    // 鼠标移动(onmousemove)时计算每次移动的横向距离和纵向距离的变化值，并改变元素的 left 和 top 值。
    // 鼠标松开(onmouseup)时完成一次拖拽。
    draggable: {
        mounted(el, binding) {
            el.style.position = 'absolute';
            el.style.cursor = 'move';
            el.style.userSelect = 'none';

            const parent = el.parentElement;
            parent.style.position = 'relative'


            const { instance } = binding;
            const { left: parentLeft, top: parentTop } = parent.getBoundingClientRect();

            let offsetX = 0;
            let offsetY = 0;
            let isDragging = false;

            function handleMouseDown(e) {
                if (el.contains(e.target)) {
                    isDragging = true;
                    offsetX = e.clientX - el.getBoundingClientRect().left;
                    offsetY = e.clientY - el.getBoundingClientRect().top;
                }
            }

            function handleMouseMove(e) {
                if (!isDragging) return;

                const scrollLeft = parent.scrollLeft || window.pageXOffset || document.documentElement.scrollLeft;
                const scrollTop = parent.scrollTop || window.pageYOffset || document.documentElement.scrollTop;

                const x = e.clientX - parentLeft - offsetX + scrollLeft;
                const y = e.clientY - parentTop - offsetY + scrollTop;

                const maxX = parent.clientWidth - el.offsetWidth;
                const maxY = parent.clientHeight - el.offsetHeight;

                const clampedX = Math.max(0, Math.min(x, maxX));
                const clampedY = Math.max(0, Math.min(y, maxY));

                // console.log(scrollLeft, scrollTop, 'scroll');
                // console.log(x, y, 'xy');
                // console.log(maxX, maxY, 'max');
                // console.log(clampedX, clampedY, 'clamped');
                // console.log(offsetX, offsetY, 'offset');

                el.style.left = `${clampedX}px`;
                el.style.top = `${clampedY}px`;
            }

            function handleMouseUp() {
                isDragging = false;
            }

            const throttledMouseMove = throttle(ref(handleMouseMove), 16)

            instance.handleMouseDown = handleMouseDown;
            instance.handleMouseMove = throttledMouseMove.value;
            instance.handleMouseUp = handleMouseUp;



            window.addEventListener('mousedown', handleMouseDown);
            window.addEventListener('mousemove', throttledMouseMove.value);
            window.addEventListener('mouseup', handleMouseUp);
        },
        unmounted(el, binding) {
            const { instance } = binding;
            window.removeEventListener('mousedown', instance.handleMouseDown);
            window.removeEventListener('mousemove', instance.handleMouseMove);
            window.removeEventListener('mouseup', instance.handleMouseUp);
        },
    },
    // v-track //不建议使用
    // 声明式埋点是在具体DOM元素上进行数据绑定，只需组件开发人员在sdk上制定埋点方案，业务开发人员设置数据即可，优点是埋点代码与具体的交互和业务逻辑解耦
    track: {
        mounted(el, binding) {
            const { arg, value } = binding;
            const url = '' //上传的url
            if (!arg) {
                console.error('v-track directive requires an event type argument.');
                return;
            }

            const eventHandler = () => {
                console.log(`事件是${arg}`);
                console.log(`数据是${JSON.stringify(value)}`);
                navigator.sendBeacon(url, value)
                // 进行埋点请求
            };

            el.addEventListener(arg, eventHandler);

            el._cleanup = () => {
                el.removeEventListener(arg, eventHandler);
            };
        },

        beforeUnmount(el) {
            el._cleanup && el._cleanup();
        }
    }
}